package org.example.mallweb.mallservice.service.serviceimpl;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.example.mallcommon.dto.ItemListDto;
import org.example.mallcommon.dto.ItemsDto;
import org.example.mallcommon.projo.OrderItems;
import org.example.mallcommon.projo.Orders;
import org.example.mallcommon.result.ReturnResult;
import org.example.mallcommon.tool.OrderNoGenerator;
import org.example.mallcommon.vio.OrderItemsVio;
import org.example.mallweb.mallservice.mq.DelayExchangeProvider;
import org.example.mallweb.mallservice.mybatiscommon.order.OrderItemsMapper;
import org.example.mallweb.mallservice.mybatiscommon.order.OrderMapper;
import org.example.mallweb.mallservice.service.OrderService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 韩先楚
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderItemsMapper orderItemsMapper;

    @Resource
    private DelayExchangeProvider delayExchangeProvider;

    @Value("${delay.queue.time}")
    private String delayQueueName;

    /**
     * 创建订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult<OrderItemsVio> createOrder(ItemListDto itemListDto) {
        //先创建订单
        Orders orders = new Orders();
        orders.setOrderNo(OrderNoGenerator.generateOrderNo());
        orders.setUserId(itemListDto.getUserId());
        orders.setSellerId(itemListDto.getSellerId());
        BigDecimal totalPrice = itemListDto.getItems().stream()
                .map((Function<ItemsDto, BigDecimal>) itemsDto -> itemsDto.getPrice())
                .reduce(new BigDecimal(0), (bigDecimal, bigDecimal2) -> bigDecimal.add(bigDecimal2));
        orders.setTotalAmount(totalPrice);
        orders.setStatus(0);
        orders.setCreateTime(new Date());
        orderMapper.insert(orders);
        //再创建商品订单项
        List<OrderItems> itemsList = itemListDto.getItems().stream()
                .map(itemsDto -> {
                    OrderItems orderItems = BeanUtil.copyProperties(itemsDto, OrderItems.class);
                    orderItems.setOrderId(orders.getId());
                    return orderItems;
                }).collect(Collectors.toList());
        orderItemsMapper.insertList(itemsList);
        //再启动mq消息队列计时 20s后自动取消订单
        delayExchangeProvider.sendMessage(orders.getId(), Long.parseLong(delayQueueName));
        //返回数据
        OrderItemsVio orderItemsVio = BeanUtil.copyProperties(orders, OrderItemsVio.class);
        orderItemsVio.setItems(itemListDto.getItems());
        return ReturnResult.success(orderItemsVio);
    }

    /**
     * 取消订单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult<String> cancelOrder(Integer orderId) {
        Orders orders = orderMapper.selectById(orderId);
        if (orders.getStatus() !=0)
        {
         return    ReturnResult.error("订单已支付或已完成，无法取消");
        }
        log.info("订单取消");
        //订单状态改为3 已取消
        orders.setStatus(3);
        //设置完成时间
        orders.setFinishTime(new Date());
       orderMapper.updateById(orders);
       return ReturnResult.success("取消成功");
    }

    /**
     * 模拟支付
     * @param orderId
     * @return
     */
    @Override
    public ReturnResult<String> pay(Integer orderId) {
        Orders orders = orderMapper.selectById(orderId);
        if (orders.getStatus() !=0)
            throw new RuntimeException("订单已取消");
        orders.setId(orderId);
        orders.setStatus(1);
        orders.setPayTime(new Date());
        orderMapper.updateById(orders);
        //Todo 交易记录保存
        return ReturnResult.success("支付成功");
    }


    /**
     * 收货确认
     */
    @Override
    public ReturnResult<String> confirmOrder(Integer orderId) {
        Orders orders = orderMapper.selectById(orderId);
        if (orders.getStatus() !=1)
            throw new RuntimeException("收货失败");
        orders.setStatus(2);
        orders.setFinishTime(new Date());
        orderMapper.updateById(orders);
        return ReturnResult.success("收货成功");
    }


    /**
     *获取全部订单信息
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getAllOrder(Integer userId) {
    List<OrderItemsVio>  list  =   orderMapper.selectAllOrders(userId,null);
       return ReturnResult.success(list);
    }

    /**
     * 待收货订单
     * @param userId
     * @return
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getWaitReceiveOrder(Integer userId) {
        List<OrderItemsVio>  list  =   orderMapper.selectAllOrders(userId,1);
        return ReturnResult.success(list);
    }

    /**
     * 待支付订单
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getWaitPayOrder(Integer userId) {
        List<OrderItemsVio>  list  =   orderMapper.selectAllOrders(userId,0);
        return ReturnResult.success(list);
    }

    /**
     * 已完成订单
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getFinishOrder(Integer userId) {
        List<OrderItemsVio>  list  =   orderMapper.selectAllOrders(userId,2);
        return ReturnResult.success(list);
    }

    /**
     * 已取消订单
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getCancelOrder(Integer userId) {
        List<OrderItemsVio>  list  =   orderMapper.selectAllOrders(userId,3);
        return ReturnResult.success(list);
    }

    /**
     * 待发货订单
     * @param userId
     * @return
     */
    @Override
    public ReturnResult<List<OrderItemsVio>> getWaitSendOrder(Integer userId) {
        List<OrderItemsVio>  list  =   orderMapper.selectWaitSendOrders(userId);
        return ReturnResult.success(list);
    }

    /**
     * 删除订单
     */
    @Override
    public ReturnResult<String> deleteOrder(Integer orderId) {
        orderMapper.deleteById(orderId);
        return ReturnResult.success("删除成功");
    }


}
